// 一般的项目都会有一个类型的专门封装axios的模块
// 细节上可能有区别  三个封装逻辑 不挑项目

// 三个关键点
// 1. 调用create方法创建一个实例(接口根路径, 超时时间)
// 2. 请求拦截器 (在发送请求之前在请求头中 request headers 添加token)
// 3. 响应拦截器 (token失效的处理 401 跳转到登录 清空本地的token)

// 如何实际编码 -> 看文档复制

import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import router from '@/router'

// 创建一个axios实例
const service = axios.create({
  // 代码不变的情况下随着你启动不同的环境
  // 接口根地址就会发生变化
  baseURL: process.env.VUE_APP_BASE_API, // 根地址
  timeout: 5000 // 超时时间
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    // config请求参数 可以在这里添加token
    // 这里千万记着return
    // 1. 获取本地token(都可以的)
    // 2. 注入到request header中
    const token = store.state.user.token
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  // 成功和失败回调的判断条件是什么？
  // http状态码决定的！！200-300 认为成功状态
  // 如果当前http状态码 不在200-300之间 认为错误状态 执行失败回调
  // 这里可以先点data 数据传到业务组件中时就不需要data了

  // 错误优化方案：通过后端返回的自定义错误字段success手动判断当前接口是否成功
  res => {
    const { data, message, success } = res.data
    if (success) {
      // 接口成功 把后端接口数据return
      // 某个接口它有很多种状态 10001 已购买 10002 已支付 10003 已下架
      return data
    } else {
      // 接口失败了 模仿原来的错误操作 把错误提示语传入
      // 给到用户一个比较明显的弹框提示
      Message.warning(message)
      return Promise.reject(message)
    }
  },
  error => {
    // 获取401状态码
    // 清除过期的token 跳回到登录页
    console.dir(error)
    if (error.response && error.response.status && error.response.status === 401) {
      // mutation
      store.commit('user/removeInfo')
      // 在哪个路由下发生的失效 将来登录之后调回来
      router.push(`/login?redirect=${router.currentRoute.fullPath}`)
    }
    return Promise.reject(error)
  }
)

export default service
